package gtt

import (
	"github.com/google/uuid"
	"strings"
	"sync"
	"time"
)

var gtt = tt{
	DataAllChan: make(chan Data, 200), // 数据通道
	On:          map[string]map[string]Bus{},
	mu:          sync.RWMutex{},
}

func init() {
	go ck()
	go dtime()
}
func ck() {
	for {
		data := <-gtt.DataAllChan
		on, ok := gtt.On[data.ReceiveName]
		if !ok {
			continue
		}
		for _, bus := range on {
			if data.ReceiveId != "" && bus.Id != data.ReceiveId {
				continue
			}
			if bus.Call == nil {
				bus.Close()
				continue
			}
			go func(data2 Data) {
				defer func() {
					recover() // 防止内存泄漏
				}()
				rdata := bus.Call(data2)
				if rdata == nil {
					return
				}
				if data2.SendName == "" {
					return
				}
				gtt.DataAllChan <- Data{
					SendName:    data2.ReceiveName,
					SendId:      data2.ReceiveId,
					ReceiveName: data2.SendName,
					ReceiveId:   data2.SendId,
					Data:        rdata,
					Time:        time.Now().Unix(),
				}
			}(data)
		}
	}
}
func dtime() {
	for {
		for _, on := range gtt.On {
			for _, bus := range on {
				//默认消息不接收数据
				if bus.Call == nil {
					bus.Close()
					continue
				}
			}
		}
		time.Sleep(time.Second * 10)
	}
}
func GetName(name ...string) string {
	lname := "临时消息"
	if len(name) > 0 {
		lname = name[0]
	}
	SendName, SendId := creatName(lname)
	return SendName + "." + SendId
}

// 获取一次监听
func ListenOnce(Name string, t ...int) []byte {
	var outtime = 10 * time.Second
	if len(t) > 0 {
		if t[0] > 0 {
			outtime = time.Duration(t[0]) * time.Millisecond
		}
	}
	newData := make(chan []byte, 1)
	defer close(newData)
	//创建建通
	bus := On(Name, func(ondata Data) []byte {
		newData <- ondata.Data
		return nil
	})
	defer bus.Close()

	var timer *time.Timer
	timer = time.NewTimer(outtime)
	defer timer.Stop()
	select {
	case <-timer.C:
		return nil
	case d := <-newData:
		return d
	}
}
func Get(Name string, data []byte, t ...int) []byte {
	var outtime = 10 * time.Second
	if len(t) > 0 {
		if t[0] == 0 {
			Emit(Name, data)
			return nil
		}
		if t[0] > 0 {
			outtime = time.Duration(t[0]) * time.Millisecond
		}
	}
	newData := make(chan []byte, 1)
	defer close(newData)
	//创建建通
	SendName, SendId := creatName("临时消息")
	bus := On(SendName+"."+SendId, func(ondata Data) []byte {
		newData <- ondata.Data
		return nil
	})
	defer bus.Close()

	ReceiveName, ReceiveId := getName(Name)

	gtt.DataAllChan <- Data{
		SendName:    SendName,
		SendId:      SendId,
		ReceiveName: ReceiveName,
		ReceiveId:   ReceiveId,
		Data:        data,
		Time:        time.Now().Unix(),
	}

	var timer *time.Timer
	timer = time.NewTimer(outtime)
	defer timer.Stop()
	select {
	case <-timer.C:
		return nil
	case d := <-newData:
		return d
	}
}
func Emit(Name string, data []byte) {
	ReceiveName, ReceiveId := getName(Name)
	gtt.DataAllChan <- Data{
		SendName:    "",
		SendId:      "",
		ReceiveName: ReceiveName,
		ReceiveId:   ReceiveId,
		Data:        data,
		Time:        time.Now().Unix(),
	}
}

func On(Name string, Call func(data Data) []byte) *Bus {
	ReceiveName, ReceiveId := creatName(Name)

	//生成uuid
	bus := &Bus{
		Id:   ReceiveId,
		Name: ReceiveName,
		Call: Call,
	}
	gtt.mu.Lock()
	defer gtt.mu.Unlock()
	if _, ok := gtt.On[ReceiveName]; !ok {
		gtt.On[ReceiveName] = map[string]Bus{}
	}
	gtt.On[ReceiveName][ReceiveId] = *bus
	return bus
}

func (this *Bus) Close() {
	if _, ok := gtt.On[this.Name]; !ok {
		return
	}
	gtt.mu.Lock()
	defer gtt.mu.Unlock()
	delete(gtt.On[this.Name], this.Id)
	if len(gtt.On[this.Name]) == 0 {
		delete(gtt.On, this.Name)
	}
}
func getName(name string) (ReceiveName, ReceiveId string) {
	//字符串分割
	names := strings.Split(name, ".")
	ReceiveName = name
	if len(names) > 1 {
		ReceiveName = names[0]
		ReceiveId = names[1]
	}
	return
}
func creatName(name string) (ReceiveName, ReceiveId string) {
	//字符串分割
	names := strings.Split(name, ".")
	ReceiveName = name
	if len(names) > 1 {
		ReceiveName = names[0]
		ReceiveId = names[1]
	}
	if ReceiveId == "" {
		ReceiveId = uuid.New().String()
	}
	return
}
